package com.daffodil.storage.client;

import java.io.InputStream;
import java.util.Set;

import com.github.tobato.fastdfs.domain.fdfs.FileInfo;
import com.github.tobato.fastdfs.domain.fdfs.MetaData;
import com.github.tobato.fastdfs.domain.fdfs.StorageNode;
import com.github.tobato.fastdfs.domain.fdfs.StorageNodeInfo;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadCallback;
import com.github.tobato.fastdfs.domain.proto.storage.StorageDeleteFileCommand;
import com.github.tobato.fastdfs.domain.proto.storage.StorageDownloadCommand;
import com.github.tobato.fastdfs.domain.proto.storage.StorageGetMetadataCommand;
import com.github.tobato.fastdfs.domain.proto.storage.StorageQueryFileInfoCommand;
import com.github.tobato.fastdfs.domain.proto.storage.StorageSetMetadataCommand;
import com.github.tobato.fastdfs.domain.proto.storage.StorageUploadFileCommand;
import com.github.tobato.fastdfs.domain.proto.storage.enums.StorageMetadataSetType;

import cn.hutool.core.util.ObjectUtil;

/**
 * 
 * @author yweijian
 * @date 2023年10月31日
 * @version 1.0
 * @description
 */
public class FastdfsStorageClient {

    private FastdfsTrackerClient trackerClient;

    public FastdfsStorageClient(FastdfsTrackerClient trackerClient) {
        super();
        this.trackerClient = trackerClient;
    }

    /**
     * 上传不支持断点续传的文件
     * @param groupName
     * @param inputStream
     * @param fileSize
     * @param fileExtName
     * @param metaData
     * @return
     */
    public StorePath uploadFile(String groupName, InputStream inputStream, long fileSize, String fileExtName, Set<MetaData> metaData) {
        StorageNode client = trackerClient.getStoreStorage(groupName);
        StorageUploadFileCommand command = new StorageUploadFileCommand(client.getStoreIndex(), inputStream,
                fileExtName, fileSize, false);
        StorePath storePath = trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), command);
        // 上传metadata
        if (ObjectUtil.isNotEmpty(metaData)) {
            StorageSetMetadataCommand setMDCommand = new StorageSetMetadataCommand(storePath.getGroup(), storePath.getPath(),
                    metaData, StorageMetadataSetType.STORAGE_SET_METADATA_FLAG_OVERWRITE);
            trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), setMDCommand);
        }
        return storePath;
    }

    /**
     * 获取metadata
     * @param groupName
     * @param path
     * @return
     */
    public Set<MetaData> getMetadata(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageGetMetadataCommand command = new StorageGetMetadataCommand(groupName, path);
        return trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 查询文件信息
     * @param groupName
     * @param path
     * @return
     */
    public FileInfo queryFileInfo(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageQueryFileInfoCommand command = new StorageQueryFileInfoCommand(groupName, path);
        return trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 删除文件
     * @param groupName
     * @param path
     */
    public void deleteFile(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getUpdateStorage(groupName, path);
        StorageDeleteFileCommand command = new StorageDeleteFileCommand(groupName, path);
        trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 下载整个文件
     * @param groupName
     * @param path
     * @param callback
     * @return
     */
    public <T> T downloadFile(String groupName, String path, DownloadCallback<T> callback) {
        return this.downloadFile(groupName, path, 0, 0, callback);
    }

    /**
     * 下载文件片段
     * @param groupName
     * @param path
     * @param fileOffset
     * @param fileSize
     * @param callback
     * @return
     */
    public <T> T downloadFile(String groupName, String path, long fileOffset, long fileSize, DownloadCallback<T> callback) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageDownloadCommand<T> command = new StorageDownloadCommand<T>(groupName, path, fileOffset, fileSize, callback);
        return trackerClient.getTrackerConnectionManager().executeFdfsCmd(client.getInetSocketAddress(), command);
    }
}
